<script setup lang="ts">
import HandsonTable from 'handsontable'
import { registerAllModules } from 'handsontable/registry'
import 'handsontable/styles/handsontable.css'
import 'handsontable/styles/ht-theme-main.css'
// import 'handsontable/styles/ht-theme-horizon.css'
import '@/style/handsontable-theme.css'
import { registerLanguageDictionary, zhCN } from 'handsontable/i18n'
import { HyperFormula } from 'hyperformula'
import useTheme from '../useTheme'
import useReportDetail, { type LoadReportResponse } from '../useReportDetail'
import { saveReportDataOfCompanyElectricity, updateReportDataOfCompanyElectricity, loadOutsideCompanyList } from '@/api/modules/dataReport'
import type { SaveParams } from '../type'
import { REPORT_FORM_ID, REPORT_ID } from '@/enum'
import { READONLY_CELL_CLASS, ROUND_NUMBER } from '../config'
import useValidate from '../useValidate'

defineOptions({ name: 'CompanyEelectricity' })

const props = defineProps<{
  time: string
  socialCreditCode: string
  company: string
  readonly?: boolean
  /** 加载远程数据时使用的ID */
  dataId?: number
}>()

registerLanguageDictionary(zhCN)

// register Handsontable's modules
registerAllModules()

// 外转供电KEYS
const WZGD_KEYS = [
  // '用户名称',
  'name',
  // '线路名称',
  'lineName',
  // '起码',
  'startQuantity',
  // '止码',
  'endQuantity',
  // '倍率',
  'ratio',
  // '电量（kwh）',
  'electricQuantity',
  // '电价',
  'electroValence',
  // '电费（元）',  后端没有定义，因为用不上
  'electricPrice',
  // '备注',
  'reamak',
]

const HEADERS = [
  [
    '项目',
    null,
    '电量（kw·h)',
    null,
    null,
    '电费（元）',
    null,
    '发票电费（元）',
    '电价（元/kwh）',
    null,
  ],
  [
    '购电情况',
    '电业局结算数（合计）',
      `=ROUND(C3+G9,${ROUND_NUMBER})`,
      null,
      null,
      `=ROUND(F3+I9,${ROUND_NUMBER})`,
      null,
      '',
      `=IFERROR(ROUND(F2/C2,${ROUND_NUMBER}), "")`,
      null,
  ],
  [
    '本单位用电',
    '本公司（厂、矿）发行数',
      `=ROUND(C4+C5,${ROUND_NUMBER})`,
      null,
      null,
      `=ROUND(F4+F5,${ROUND_NUMBER})`,
      null,
      '',
      `=IFERROR(ROUND(F3/C3,${ROUND_NUMBER}), "")`,
      null,
  ],
  [
    null,
      `${props.company ?? ''}煤矿`,
      '',
      null,
      null,
      '',
      null,
      null,
      `=IFERROR(ROUND(F4/C4,${ROUND_NUMBER}), "")`,
      null,
  ],
  [
    null,
      `${props.company ?? ''}洗煤厂`,
      '',
      null,
      null,
      '',
      null,
      null,
      `=IFERROR(ROUND(F5/C5,${ROUND_NUMBER}), "")`,
      null,
  ],
  [
    '外转供电',
    '用户名称',
    '线路名称',
    '起码',
    '止码',
    '倍率',
    '电量（kwh）',
    '电价',
    '电费（元）',
    '备注',
  ],
  [null, '', '', '', '', '', '', '', `=ROUND(G7*H7,${ROUND_NUMBER})`, ''],
  [null, '', '', '', '', '', '', '', `=ROUND(G8*H8,${ROUND_NUMBER})`, ''],
  [
    null,
    '合计',
    '',
    '',
    '',
    '',
      `=ROUND(SUM(G7:G8),${ROUND_NUMBER})`,
      `=IFERROR(ROUND(I9/G9,${ROUND_NUMBER}), "")`,
      `=ROUND(SUM(I7:I8),${ROUND_NUMBER})`,
      '',
  ],
  [
    '备注',
    '电费以及单价均为含税金额',
    null,
    null,
    null,
    null,
    null,
    null,
    null,
    null,
  ],
]

const loadReportResponse = shallowRef<LoadReportResponse>()

const wrapper = ref<HTMLElement>()
const hot = ref<HandsonTable>()

const newMergeCells = shallowRef<HandsonTable.GridSettings['mergeCells']>(
  [
    { row: 0, col: 0, rowspan: 1, colspan: 2 },
    { row: 0, col: 2, rowspan: 1, colspan: 3 },
    { row: 0, col: 5, rowspan: 1, colspan: 2 },
    { row: 0, col: 8, rowspan: 1, colspan: 2 },
    { row: 2, col: 0, rowspan: 3, colspan: 1 },
    { row: 5, col: 0, rowspan: 4, colspan: 1 },
    { row: 1, col: 2, rowspan: 1, colspan: 3 },
    { row: 2, col: 2, rowspan: 1, colspan: 3 },
    { row: 3, col: 2, rowspan: 1, colspan: 3 },
    { row: 1, col: 5, rowspan: 1, colspan: 2 },
    { row: 2, col: 5, rowspan: 1, colspan: 2 },
    { row: 3, col: 5, rowspan: 1, colspan: 2 },
    { row: 4, col: 5, rowspan: 1, colspan: 2 },
    { row: 4, col: 2, rowspan: 1, colspan: 3 },
    { row: 1, col: 8, rowspan: 1, colspan: 2 },
    // { row: 1, col: 7, rowspan: 4, colspan: 1 },
    { row: 2, col: 8, rowspan: 1, colspan: 2 },
    { row: 3, col: 8, rowspan: 1, colspan: 2 },
    { row: 4, col: 8, rowspan: 1, colspan: 2 },
    { row: 9, col: 1, rowspan: 1, colspan: 9 },
  ],
)

const { getReportDataById, beforeChangeHook } = useReportDetail()

// 获取字符所在行号
function getRowNumber(value: string) {
  if (hot.value) {
    return hot.value.getSourceData().findIndex(item => item.includes(value))
  }
  return -2
}

// 加载数据
async function loadData() {
  let dataList = [...HEADERS]

  // 加载远程数据
  if (props.dataId) {
    // 加载 data
    // 加载 mergeCells
    const data = await getReportDataById(props.dataId)
    loadReportResponse.value = data
    if (data.webReportData) {
      try {
        dataList = JSON.parse(data.webReportData) as any[]
      }
      catch (e) {
        console.error(e)
        ElMessage.error('[webReportData]数据解析错误')
        dataList = [...HEADERS]
      }
    }
    if (data.webReportFormat) {
      try {
        newMergeCells.value = JSON.parse(data.webReportFormat).mergeCells
      }
      catch (e) {
        console.error(e)
      }
    }
  }
  else {
    const y = props.time.split('-')[0]
    // 未填写 需要加载外转供电单位的并集
    const { data: zs } = await loadOutsideCompanyList(
      +y,
      props.socialCreditCode,
    )
    if (zs && zs.length) {
      dataList = HEADERS.slice(0, 6)
      const start = 7
      const end = zs.length + start
      // 外转供电单位
      for (const z of zs) {
        const i = zs.indexOf(z)
        const row = start + i
        dataList.push([null, z, '', '', '', '', '', '', `=ROUND(G${row}*H${row},${ROUND_NUMBER})`, ''])
      }
      // 合计
      dataList.push([
        null,
        '合计',
        '',
        '',
        '',
        '',
          `=ROUND(SUM(G${start}:G${end - 1}),${ROUND_NUMBER})`,
          `=IFERROR(ROUND(I${end}/G${end},${ROUND_NUMBER}), "")`,
          `=ROUND(SUM(I${start}:I${end - 1}),${ROUND_NUMBER})`,
          '',
      ])
      // 备注
      dataList.push([
        '备注',
        '电费以及单价均为含税金额',
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
      ])

      // 更新 newMergeCells
      const mc = (newMergeCells.value as any).slice(0)
      const a = mc.find((item: any) => item.row === 5 && item.col === 0)
      const b = mc.find((item: any) => item.row === 9 && item.col === 1)
      if (a) {
        a.rowspan = zs.length + 2
      }
      if (b) {
        b.row = end
      }
      newMergeCells.value = mc
    }
  }
  hot.value?.loadData([
    ...dataList,
  ])
}

// 获取类型为字符的单元格
// 外转供电的用户名称和线路名称是字符串
function getNumericCells() {
  const cells = [
    { row: 1, col: 7 },
    { row: 3, col: 2 },
    { row: 3, col: 8 },
    { row: 4, col: 2 },
    { row: 4, col: 8 },
  ]
  const r = hot.value?.countRows()
  // 开始的行号
  let row = 6
  // 8行以上才说明有外转供电数据
  if (r && r > 8) {
    // 最后的行号
    const l = r - 3
    while (row <= l) {
      cells.push({ row, col: 3 })
      cells.push({ row, col: 4 })
      cells.push({ row, col: 5 })
      cells.push({ row, col: 6 })
      cells.push({ row, col: 7 })
      row++
    }
  }
  return cells
}

// 更新单元格只读或不可编辑
function updateReadonly(): void {
  if (hot.value) {
    // 备注所在行
    const r = hot.value?.countRows() - 1
    // 第1、6行，只读；备注所在行只读；合计所在行（备注上一行）只读 或在只读模式下（如：总公司审核）
    const cells = (row: number) => {
      return row === 0 || row == 5 || row === r || row === r - 1 || props.readonly
        ? { readOnly: true }
        : {}
    }
    // 第1、8列，只读
    const columns = (index: number) => {
      return {
        readOnly: index === 0 || index === 8 || props.readonly,
      }
    }

    const cell = [
      { row: 1, col: 1, readOnly: true },
      { row: 2, col: 1, readOnly: true },
      { row: 3, col: 1, readOnly: true },
      { row: 4, col: 1, readOnly: true },
      { row: 1, col: 2, readOnly: true },
      { row: 2, col: 2, readOnly: true },
      { row: 1, col: 5, readOnly: true },
      { row: 2, col: 5, readOnly: true },
      { row: 2, col: 7, readOnly: true },
      { row: 3, col: 7, readOnly: true },
      { row: 4, col: 7, readOnly: true },
      { row: 1, col: 8, readOnly: true },
      { row: 2, col: 8, readOnly: true },
      // 煤矿的电价，2025年4月7日修改电价为自动计算
      { row: 3, col: 8, readOnly: true },
      // 洗煤厂的电价，2025年4月7日修改电价为自动计算
      { row: 4, col: 8, readOnly: true },

      // 备注行第1列居左对齐
      { row: r, col: 1, className: 'htLeft' },
    ] as any[]
    hot.value.updateSettings({
      cell,
      cells,
      columns,
    })
  }
}

// 更新单元格合并
function updateMergeCells() {
  if (hot.value) {
    hot.value.updateSettings({
      mergeCells: newMergeCells.value,
    })
  }
}

function updateNumericCells() {
  const cells = getNumericCells()
  for (const { row, col } of cells) {
    if (row > 5 && col === 7) {
      hot.value?.setCellMetaObject(row, col, {
        type: 'numeric',
        numericFormat: {
          pattern: `0.0000`,
        },
      })
    }
    else {
      hot.value?.setCellMeta(row, col, 'type', 'numeric')
    }
  }
}

// 更新单元格的公式
function updateFormulas() {
  if (hot.value) {
    // 合计行索引
    const r = hot.value?.countRows() - 2
    if (r < 7) {
      // 没有可以合计的行
      return
    }
    // 更新总计行中的“电量”
    hot.value.setSourceDataAtCell(r, 6, `=ROUND(SUM(G7:G${r}),${ROUND_NUMBER})`)
    // 更新总计行中的“电费”
    hot.value.setSourceDataAtCell(r, 8, `=ROUND(SUM(I7:I${r}),${ROUND_NUMBER})`)
    // 更新活动行中的“电费” =电量*电价
    for (let startRow = 6; startRow < r; startRow++) {
      hot.value.setSourceDataAtCell(startRow, 8, `=ROUND(G${startRow + 1}*H${startRow + 1},${ROUND_NUMBER})`)
    }

    // 更新电业局结算数电量(C2)和电费(F2)
    hot.value.setSourceDataAtCell(1, 2, `=ROUND(C3+G${r + 1},${ROUND_NUMBER})`)
    hot.value.setSourceDataAtCell(1, 5, `=ROUND(F3+I${r + 1},${ROUND_NUMBER})`)
  }
}

function init() {
  if (!wrapper.value)
    return
  hot.value = new HandsonTable(wrapper.value, {
    selectionMode: 'single',
    readOnly: props.readonly,
    // disableVisualSelection: props.readonly,
    language: zhCN.languageCode,
    formulas: {
      engine: HyperFormula,
    },
    className: 'htCenter htMiddle',
    readOnlyCellClassName: READONLY_CELL_CLASS,
    stretchH: 'all',
    manualColumnResize: true,
    colHeaders: true,
    rowHeaders: true,
    contextMenu: props.readonly
      ? false
      : {
          items: {
            row_above: {
              disabled() {
                // 不能“insert row above”的条件是
                // 1、在“外转供电-用户名称”所在行之上（含）
                // 或
                // 2、在“外转供电-合计”所在行之下（不含）
                const r1 = getRowNumber('用户名称')
                const r2 = getRowNumber('合计')
                const [startRow] = this.getSelectedLast() ?? []
                if (startRow) {
                  return startRow <= r1 || startRow > r2
                }
                return true
              },
            },
            row_below: {
              disabled() {
                // 不能“insert row below”的条件是
                // 1、在“外转供电-用户名称”所在行之上（不含）
                // 或
                // 2、在“外转供电-合计”所在行之下（含）
                const r1 = getRowNumber('用户名称')
                const r2 = getRowNumber('合计')
                const [startRow] = this.getSelectedLast() ?? []
                if (startRow) {
                  return startRow < r1 || startRow >= r2
                }
                return true
              },
            },
            remove_row: {
              disabled() {
                // 只能删除”用户名称“与”合计“之间的行
                const r1 = getRowNumber('用户名称')
                const r2 = getRowNumber('合计')
                const [startRow] = this.getSelectedLast() ?? []
                if (startRow) {
                  return startRow <= r1 || startRow >= r2
                }
                return true
              },
            },
            sq1: '---------',
            undo: {
              callback() {
                this.getPlugin('undoRedo').undo()
              },
            },
            redo: {
              callback() {
                this.getPlugin('undoRedo').redo()
              },
            },
          },
        },
    mergeCells: [],
    licenseKey: 'non-commercial-and-evaluation',
  })

  // 处理输入的值，parseFloat
  hot.value.addHook('beforeChange', beforeChangeHook(() => {
    const r = hot.value?.countRows() ?? 0
    const ret = []
    if (r > 8) {
      let row = 6
      while (row < r - 2) {
        // 用户名称、线路名称、备注
        ret.push([row, '1'] as [number, string])
        ret.push([row, '2'] as [number, string])
        ret.push([row, '9'] as [number, string])
        // 外转供电电价使用numberFormat单独处理
        ret.push([row, '7'] as [number, string])
        row++
      }
    }
    return ret
  }))

  // 选中单元格后可以直接输入
  hot.value.addHook('afterSelectionEnd', (row, col) => {
    if (props.readonly)
      return
    if (row < 0 || col < 0)
      return
    const value = hot.value?.getSourceDataAtCell(row, col)
    hot.value?.getActiveEditor()?.beginEditing()
    hot.value?.getActiveEditor()?.setValue(value)
  })

  // 增加行后
  hot.value.addHook('afterCreateRow', () => {
    const m = hot.value?.getPlugin('mergeCells')
    // 更新要合并单元格
    newMergeCells.value = (m as any).mergedCellsCollection.mergedCells
    // 更新单元格只读或不可编辑
    updateReadonly()
    // 更新单元格的公式
    updateFormulas()
    // 更新单元格类型
    updateNumericCells()
  })
  // 删除行后
  hot.value.addHook('afterRemoveRow', () => {
    const m = hot.value?.getPlugin('mergeCells')
    // 更新要合并单元格
    newMergeCells.value = (m as any).mergedCellsCollection.mergedCells
    // 更新单元格只读或不可编辑
    updateReadonly()
    // 更新单元格的公式
    updateFormulas()
    // 更新单元格类型
    updateNumericCells()
  })

  // debug
  if (import.meta.env.VITE_REPORT_DEBUG === '1') {
    hot.value.addHook('afterSelection', (row, col) => {
      if (row > -1 && col > -1) {
        console.info(`[${row},${col}] ${hot.value?.getSourceDataAtCell(row, col)}`)
        document.execCommand('copy')
        // console.info(`[${row},${col}]`, hot.value?.getCellMeta(row, col))
      }
    })
  }
}

// 更新由旧数据造成的单价公式问题
function fixPriceFormula() {
  hot.value?.setSourceDataAtCell(3, 8, '=IFERROR(ROUND(F4/C4,4), "")')
  hot.value?.setSourceDataAtCell(4, 8, '=IFERROR(ROUND(F5/C5,4), "")')
}

async function bootstrap() {
  // 初始化实例
  init()
  // 加载数据和配置
  await loadData()
  // fixPriceFormula()
  // 更新单元格合并
  updateMergeCells()
  // 更新单元格只读或不可编辑
  updateReadonly()
  // 更新单元格的公式
  updateFormulas()
  // 更新单元格类型
  updateNumericCells()

  hot.value?.render()
}

const { isDark } = useTheme(async () => {
  if (hot.value) {
    hot.value.destroy()
    hot.value = undefined
    await nextTick()
    await bootstrap()
  }
})

onMounted(bootstrap)

function getSourceData() {
  return hot.value?.getSourceData() ?? []
}

function getZGDList() {
  const s = getSourceData()
  if (s.length > 0) {
    const ret = []
    for (let start = 6; start < s.length - 2; start++) {
      ret.push(
        WZGD_KEYS.reduce((acc, vv, ii) => {
          acc[vv] = (s[start] as any)[ii + 1]
          return acc
        }, {} as any),
      )
    }
    // 过滤掉全部为空的行
    return ret.filter(v => v !== '' && v !== null)
  }
  return []
}

function getSettings() {
  return {
    mergeCells: newMergeCells.value,
    sourceData: getSourceData(),
    list: getZGDList(),
    extraMapData: {
      // 煤矿电量
      mkElectricQuantity: hot.value?.getSourceDataAtCell(3, 2) ?? '',
      // 洗煤厂电量
      xmcElectricQuantity: hot.value?.getSourceDataAtCell(4, 2) ?? '',
      // 煤矿电费
      mkElectricCharge: hot.value?.getSourceDataAtCell(3, 5) ?? '',
      // 洗煤厂电费
      xmcElectricCharge: hot.value?.getSourceDataAtCell(4, 5) ?? '',
      // 发票电费
      invoiceCharge: hot.value?.getSourceDataAtCell(1, 7) ?? '',
    },
  }
}

async function save({
  saveType,
  beforeSaveFn,
  afterSaveFn,
}: SaveParams) {
  const s = getSettings()
  const src = loadReportResponse.value
  const params = {
    ...src,
    ...s.extraMapData,
    reportId: REPORT_ID.COMPANY_ELECTRICITY,
    formId: REPORT_FORM_ID.COMPANY_ELECTRICITY,
    saveType,
    zgdList: s.list,
    webReportData: JSON.stringify(s.sourceData),
    webReportFormat: JSON.stringify({
      mergeCells: s.mergeCells,
    }),
  }

  if (!hot.value)
    return
  // 校验表格数据类型
  const validate = useValidate(hot.value)
  const result = await validate().catch(() => {})
  hot.value.render()
  if (typeof result !== 'boolean') {
    return
  }

  // 保存前的回调
  let before = true
  if (beforeSaveFn) {
    before = await beforeSaveFn(
      REPORT_ID.COMPANY_ELECTRICITY,
      REPORT_FORM_ID.COMPANY_ELECTRICITY,
      params,
    )
  }
  if (before) {
    let responseId: number | undefined
    let after = true
    try {
      if (params.id) {
        await updateReportDataOfCompanyElectricity(params)
      }
      else {
        const { data } = await saveReportDataOfCompanyElectricity(params)
        responseId = data.id
      }
    }
    catch (e) {
      after = false
      hot.value.render()
    }
    // 保存后的回调
    after && afterSaveFn?.(
      REPORT_ID.COMPANY_ELECTRICITY,
      REPORT_FORM_ID.COMPANY_ELECTRICITY,
      params,
      responseId,
    )
  }
}

defineExpose({
  getSettings,
  save,
})
</script>

<template>
  <div class="h-full w-full">
    <div
      ref="wrapper" class="h-full w-full overflow-auto" :class="{
        'ht-theme-main-dark': isDark,
        'ht-theme-main': !isDark,
      }"
    />
  </div>
</template>
